-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: expose Kubeconform as a module #189
base: master
Are you sure you want to change the base?
Conversation
6280f79
to
7029e22
Compare
Hi @aabouzaid , Kubeconform can be used as a module, there is an example here: https://github.com/yannh/kubeconform/blob/master/examples/main.go - would it work for you? Your PR is pretty extensive and I'm not sure I agree with all changes... |
@yannh thanks for the link, but it's only the Kueconform individual packages that are exposed, not the app itself. That means everyone who wants to use Kueconform needs to implement the same execution logic that uses the underneath Kubeconform packages. This is a huge redundancy IMO (I'm not sure what is the actual reason not to expose the app but only its libs). Also, for example, the config is exposed, but it doesn't have any YAML or JSON tags, which also means extra work if someone wants to extend Kubeconform. So given that I don't try to use Kubeconform in my app but actually writing an interface to use Kubeconform, it's not even helpful to reimplement what you already did (KubeconformValidator is just a wrapper for Kubeconform). All changes here are minimal to make Kubeconform app reusable, so if anything is not clear, I'd be happy to clarify the reasoning behind the changes (and even remove some of the changes if they don't fit for one reason or another). Thank you 🙇 |
7029e22
to
66e2a96
Compare
@yannh I hope that's better 🙇 |
66e2a96
to
336abef
Compare
Quite a lot to like about that PR thanks 🙇 Can you expand on this "NGConfig", why that is interesting? Have a few nits here and there, but I can see where you're going. Adding a few comments for discussion in the code. |
Summary bool `yaml:"summary" json:"summary"` | ||
Verbose bool `yaml:"verbose" json:"verbose"` | ||
Version bool `yaml:"version" json:"version"` | ||
Stream *Stream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if Stream fits better here, or as a separate argument to Validate().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe in cmd/kubeconform
if it is exposed (it should be a package, not main to be reusable).
I will think of a struct and it has something like:
type Kubeconform struct {
Stream *Stream
Config *Config
}
which represents Kubeconform
as an application.
func New(outputFormat string, printSummary, isStdin, verbose bool) (Output, error) { | ||
w := os.Stdout | ||
|
||
func New(w io.Writer, outputFormat string, printSummary, isStdin, verbose bool) (Output, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I quite like the ability to override the streams here 👍
} | ||
|
||
// LoadNGConfig allows to introduce new config format/structure while keeping backward compatibility. | ||
func (c *Config) LoadNGConfig() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest leaving this out for now, to make the PR easier to merge.
@@ -0,0 +1,24 @@ | |||
package main |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kinda liked having the main function in cmd/kubeconform... I might move the validation to pkg/kubeconform.. still thinking about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw different ways to make it, but if that's your preference, maybe putting the main back in cmd/kubeconform
and just moving validate
to its own package under cmd/kubeconform/validate
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another idea, we can just put Validate()
under pkg/validator/validator.go
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've not completely made up my mind on this, I'm likely to try out something that would allow you to work, but I might reserve myself the right to break that location/interface for a little while while I find a good place for it :)
The idea of the NG config is to overcome the diversion between the input of Kubeconform and the actual data structure in the Config struct. Let's take I've read most of the code, and it's not clear to me why that data type is used if the skipped items don't have extra config. Here is an example of what I mean: kubeconform/pkg/validator/validator.go Line 118 in e3bb348
So what is the problem here?
which is confusing if anyone looked at the arg equivalent, which is The idea of NG (new generation) config is to bridge the new with the old format so
This will work out of the box, it will not introduce any breaking changes, and a deprecation note could be added. If anything is not clear, feel free to mention it, I'd be happy to add more details, |
I'll start committing parts of these to main in small commits, I ll put you as co-committer 🙇 Not impossible this will trigger a few conflicts though, but it is easier for me to do in small chunks. |
I do get the feeling behind the array. The reason it was a map was for easy lookups in here. kubeconform/pkg/validator/validator.go Line 117 in 8bc9f42
|
} | ||
|
||
if err = kubeconform.Validate(cfg, out); err != nil { | ||
fmt.Fprintf(os.Stderr, "failed validating resources: %s - %s\n", err.Error(), out) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is incorrect.. kubeconform currently returns 1 when some resources are not valid (but it didn't fail validating resources) - we need to differentiate errors processing from errors when validating..
It could return a bool saying if everything was valid or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't change the logic here, I just used what's there but with an error instead of an init.
So any return 1
became a return error
and any return 0
became a return nil
.
@@ -93,13 +83,11 @@ func realMain() int { | |||
useStdin = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we still refer to os.Stdin here instead of cfg.stream.stdin, but here we need Stat()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I put it away to think about the best way to make it.
I will get back to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hold on a bit - I'm not super happy with the signature of "Validate" yet, I would want it to enable the caller to process the results in a way they see fit. I need to think about this a bit more 🙇
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great 👌 👌
Hi again 👋
As mentioned in PR no. #170, instead of dealing with KRM inside Kubeconform, it's better to expose it as a module and use it externally.
In the PR:
app
(not aslib
) inside other applications (e.g. KubeconformValidator (a Kustomize plugin).Fixes: #160
Best Regards.